package security.IntrusionDetection.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;

import org.junit.Test;

import security.Authentication.Base.AuthenticationChain;
import security.Authentication.Base.IdentifiedUser;
import security.Authentication.Base.UnknownUser;
import security.Authentication.Base.User;
import security.Authentication.UserPass.UserPassHandler;
import security.Authentication.UserPass.UserPassRequest;
import security.Authorization.Base.AuthorizationHandler;
import security.Authorization.UserRole.UserRole;
import security.IntrusionDetection.Base.Email;
import security.IntrusionDetection.BruteforceIntrusion.BruteForceIntrusion;
import security.IntrusionDetection.IPInstrusion.IPIntrusion;
import security.LoginSystem.Base.LoginSystem;

/**
 * Test case for IntrusionDetection component
 * @author Danut
 *
 */
public class IntrusionDetectionTest {

	/**
	 * Testing the IP intrusion class. This class was meant to verify if IP's beyond 
	 * the normal patterns is trying to access the account.
	 * @throws UnknownHostException 
	 */
	@Test
	public void testIntrusionByIP() throws UnknownHostException {
		AuthenticationChain chain = new AuthenticationChain();
		InetAddress localHost = InetAddress.getLocalHost();
		UserPassRequest userPassRequest =
				new UserPassRequest(localHost, "TestUser", "Abc123!");
		IPIntrusion ipIntrusion = new IPIntrusion(new Email());
		
		//Please note that the file path is static, as such it should be changed to the path
		//in your system
		ipIntrusion.setLogFile(new File("/home/andrei/test.txt"));
		
		chain.setNext(new UserPassHandler());
		chain.setNext(ipIntrusion);
		assertTrue(chain.handleRequest(userPassRequest) instanceof IdentifiedUser);
		ipIntrusion.isPossibleIntrusion(userPassRequest);
		assertEquals(false, ipIntrusion.getEmail().getEmailSentStatus());
		
		userPassRequest = new UserPassRequest(InetAddress.getByName("4.4.4.4"), "TestUser", "Abc123!");
		assertTrue(chain.handleRequest(userPassRequest) instanceof IdentifiedUser);
		ipIntrusion.isPossibleIntrusion(userPassRequest);
		assertEquals(true, ipIntrusion.getEmail().getEmailSentStatus());
	}
	/**
	 * Testing the Brute Force intrusion method. This class was meant to check
	 * if there have been multiple attempts to access the account.
	 * @throws UnknownHostException 
	 */
	@Test
	public void testBruteForceIntrusion() throws UnknownHostException
	{
		AuthenticationChain chain = new AuthenticationChain();
		InetAddress localHost = InetAddress.getLocalHost();
		UserPassRequest userPassRequest =
				new UserPassRequest(localHost, "TestUser", "Abc123!");
		BruteForceIntrusion brute = new BruteForceIntrusion();
		chain.setNext(new UserPassHandler());
		chain.setNext(brute);
		
		assertTrue(chain.handleRequest(userPassRequest) instanceof IdentifiedUser);
		
		userPassRequest=new UserPassRequest(localHost, "QwertyUser", "Wrong pass");
		assertTrue(chain.handleRequest(userPassRequest) instanceof UnknownUser);
		
		//The following code will show that the user has been blocked due to many attempts
		//Due to some difficulties in returning the User object, I have decided to show
		//the actual result in the console, code being similar to the one in ExampleBruteForce.java
		LoginSystem log = new LoginSystem();
		log.setAuthorization(new UserRole());
		log.addIntrusionDetection(brute);
		log.addAuthentication(new UserPassHandler());
		for(int i=0;i<4;i++)
			log.login(userPassRequest);
	}
}
